Profile picture

[Spring] View Resolver

Amaranth2023년 05월 20일

들어가기 전


View란?

view는 모델이 가진 정보(데이터)를 어떻게 표현할지에 대한 로직을 가지고 있는 컴포넌트이다.

일반적인 View의 결과물은 브라우저에서 볼 수 있는 HTML 형식이고, 이 외에도 Excel, PDF, RSS 등 다양한 View 오브젝트가 존재한다.

  • View는 View 인터페이스를 구현함으로서 생성한다.
    public interface View{
        void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse resposne) throws Exception;
    }

View Type

View Resolver를 통해 원하는 View 형식(View Type)으로 View를 전달해줄 수 있다.

  • Velocity : 초기에 가장 인기를 끌던 템플릿. 유지보수가 잘 이루어지지 않아 지금은 deprecate됨.
  • FreeMarker : Apache 프로젝트 템플릿 엔진. 템플릿 및 변경 데이터를 기반으로 텍스트 출력을 생성하는 Java 라이브러리 img1.daumcdn.png
  • JsonView : API 형태로 제공할 때 가장 많이 사용하는 View
  • JSP : 국내에서 가장 많이 사용하는 표준 View(Spring boot에서는 별도의 설정을 해줘야 사용 가능하다.)
  • Thymeleaf : 의존성 추가 시 별도 설정 없이 HTML 파일로 View를 만들어줄 수 있다. HTML이지만 JSP처럼 사용할 수 있다.(Spring에서 가장 밀어주고 있는 View)

Spring에서 제공하는 View의 종류

  • InternalResourceView

    • RequestDispatcher의 forward(), include()를 사용하는 뷰.

      View view = new InternalResourceView("/WEB-INF/view/hello.jsp");
      
      return new ModelAndView(view, model);
  • RedirectView

    • HttpServletResponse의 sendRedirect() 메서드를 호출해주는 기능을 가진 뷰이다.

    • 실제 View를 생성하지는 않고, URL만 만들어 다른 페이지로 리다이렉트하게 해주는 객체이다.

    • Model 정보가 있다면 URL 뒤에 파라미터로 추가된다.

      // 뷰 사용시
      return new ModelAndView(new RedirectView("/main"));
      // 뷰 리졸버 사용시
      return new ModelAndView("redirect:/main");

      위와 같이 redirect: 접두어를 사용함으로써 View Resolver가 인식하게 할 수 있다.

  • VelocityView

  • FreeMarkerView

View Resolver란?


DispatcherServlet에 View 객체를 전달하는 방법은 크게 2가지가 있다.

  1. 컨트롤러에서 직접 View 타입의 객체를 반환하는 방법
  2. String 타입의 View 이름을 반환하는 방법*

컨트롤러에서 매번 View를 생성하여 반환하는 것(첫 번째 방법)은 비효율적이기 때문에, 스프링에서는 이 작업을 적절히 분리하여 View Resolver가 View를 선택(매핑)하고 생성하게 하였다(두 번째 방법).

View Resolver가 수행하는 작업은 다음과 같다.

  • 데이터 객체(Map, Model, ModelAndView 등이 될 수 있음)를 View 영역으로 전달하기 위해, 적절한 View 객체를 매핑한다.
  • 좀 더 구체적으로 표현하자면, View Resolver는 컨트롤러(핸들러)가 반환한 View 이름으로 그에 해당되는 View Component를 찾아 매핑한다.
  • 컨트롤러는 View의 논리적인 이름만을 반환한 뒤 역할을 종료하고, 이를 DispatcherServlet의 View Resolver가 받아 사용할 View 객체를 찾아 생성하는 작업을 수행한다.
  • 스프링 MVC 구조에서의 동작 흐름
    • Handler Mapping, Handler Adapter를 통해 Controller의 Handler가 실행되면, Handler가 처리된 ModelAndView를 반환한다.
    • 이 ModelAndView를 알맞은 View 객체로 전달해주기 위해 DispatherServlet이 View Resolver를 호출한다.
  • View Resolver는 ViewResolver 인터페이스를 구현해서 생성한다.
    public interface ViewResolver{
        View resolveViewName(String viewName, Locale locale) throws Exception;
    }

View Resolver 구현체의 종류

  • InternalResourceViewResolver
    • JSP를 처리할 수 있는 View를 반환한다.
    • 미리 지정된 접두사, 접미사를 사용해 view 이름으로 컴포넌트의 URL을 완성해주기 때문에 핸들러 쪽에서 URL을 지정하기 편리하다.
    • xml 또는 java config로 설정할 수 있다.
    • 스프링 부트에서는 자동으로 등록된다.
  • BeanNameViewResolver
    • Bean 이름으로 View를 찾아 반환한다.
    • 스프링 부트에서는 자동으로 등록된다.
  • ResourceBundleViewResolver
    • ViewResolver의 구현체로 리소스 파일을 사용한다.
    • views.properties 파일을 기본 리소스 파일로 사용한다.
  • VelocityViewResolver
  • FreeMarkerViewResolver

View Resolver의 동작 예시

Untitled

  • MVC 모델에서 JSP는 View Component로서, View를 출력하는 역할을 담당한다.

  • JSP를 실행할 땐 항상 페이지 컨트롤러를 통해 실행해야 한다.

    @Controller
    @RequestMapping("/test")
    public class Controller {
        @GetMapping
    	  public String handler(Model model) {
    
    	    model.addAttribute("name", "민성");
    	    model.addAttribute("age", 28);
    
    	    return "/jsp/test.jsp";
    	  }
    }
    • 위 코드는 { name : “민성”, age: 28 }이라는 데이터를 담은 view 객체를 반환하는 컨트롤러 핸들러 코드이다.
    • 웹 애플리케이션 디렉토리에서 /jsp/test.jsp라는 파일을 찾아 view 객체로 반환한다.
  • View와 함께 전달할 데이터를 준비하는 일은 페이지 **컨트롤러(핸들러)**가 담당한다.

  • 기본 ViewResolver는 반환 값으로 url(경로)을 받아 웹 애플리케이션 디렉토리에서 JSP를 찾는다.

  • 기본 ViewResolver를 사용할 때 핸들러가 뷰 이름을 반환하지 않으면 오류가 발생한다.

InternalResourceViewResolver 사용하기

  • XML 또는 Java Config(@Bean)으로 상세한 설정을 해줄 수 있다.

    • XML 파일로 설정하는 경우
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="prefix" value="WEB-INF/view"/>
    		<property name="suffix" value="./jsp"/>
    </bean>
    • Java Config로 설정하는 경우
    @Configuration
    @ComponentScan
    public class WebConfig{
    		@Bean
    		public ViewResolver viewResolver(){
    				InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    				resolver.setPrefix("/WEB-INF/view");
    				resolver.setSuffix(".jsp");
    				return resolver;
    		}
    }

    위와 같이 view 파일의 경로와 확장자를 접두사(Prefix), 접미사(Suffix)로 설정해주면, 핸들러는 이름만 반환하면 된다.

    @Controller
    public class HelloController {
    		@Autowired
    		HelloService helloService;
    
    		@GetMapping("/")
    		public String welcome() {
    			return "index";
    		}
    }
  • 컨트롤러(핸들러)가 반환한 URL 앞, 뒤에 접두사와 접미사를 붙여 JSP 객체를 찾는다.

  • 컨트롤러(핸들러)가 View 이름을 반환하지 않으면 RequestHandler의 URL을 View 이름으로 사용한다.

예시 코드

  1. Map 사용

    @Controller
    @RequestMapping("/test")
    public class Controller {
    
      @GetMapping
      public String handler(Map<String, Object> map) {
    
        map.put("name", "민성");
        map.put("age", 28);
    
        return "/jsp/test.jsp";
        ///WEB-INF/jsp2/jsp/test.jsp
      }
    }
    @Controller
    @RequestMapping("/test")
    public class Controller {
    
      @GetMapping
      public Map<String, Object> handler() {
    
    		HashMap<String, Object> map = new HashMap<>();
        map.put("name", "민성");
        map.put("age", 28);
    
    		return map;
        ///WEB-INF/jsp2/test.jsp
      }
    }
  2. Model 사용

    @Controller
    @RequestMapping("/test")
    public class Controller {
    
      @GetMapping
      public void handler(Model model) {
    
        model.addAttribute("name", "민성");
        model.addAttribute("age", 28);
        ///WEB-INF/jsp2/jsp/test.jsp
      }
    }
  3. ModelAndView 사용

    프론트 컨트롤러(Dispatcher Servlet)는 ModelAndView 객체에 보관되어 있는 값들을 ServletRequest 보관소로 옮기고, 설정된 View 이름을 ViewResolver로 넘긴다.

    View 이름을 지정하지 않으면 RequestHandler의 path를 ViewResolver에게 넘긴다.

    @Controller
    @RequestMapping("/test")
    public class Controller01_2 {
    
      @GetMapping
      public ModelAndView handler4() {
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("name", "민성3");
        mv.addObject("age", 28);
        mv.setViewName("/jsp/test.jsp");    //해당 코드가 없을 경우 /test
    
        return mv;
      }
    }

요약


요약하면, MVC 구조에서 View Resolver는 컨트롤러가 반환한 데이터를 담을 View 객체를 찾아 매핑하거나 생성해주는 컴포넌트이고, InternalResourceViewResolver의 경우 view 파일을 찾아 매핑하기 위한 접두사/접미사를 설정해줄 수 있다.

참고 자료


🌇 Spring : ViewResolver

[Spring MVC] 스프링 MVC 뷰 리졸버(View Resolver)

SpringMVC - Spring MVC 동작원리 - 5 (ViewResolver, DispatcherServlet 기본전략 등록 과정)

[spring] View, ViewResolver


Loading script...